package com.ndood.authenticate.browser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;

import com.ndood.authenticate.browser.handler.BrowserAuthenticationFailureHandler;
import com.ndood.authenticate.browser.handler.BrowserAuthenticationSuccessHandler;
import com.ndood.authenticate.browser.handler.BrowserLogoutSuccessHandler;
import com.ndood.authenticate.browser.session.BrowserExpiredSessionStrategy;
import com.ndood.authenticate.browser.session.BrowserInvalidSessionStrategy;
import com.ndood.authenticate.core.properties.CommonConstants;
import com.ndood.authenticate.core.properties.SecurityProperties;

/**
 * 浏览器默认Bean配置类
 * @author ndood
 */
@Configuration
public class BrowserSecurityBeanConfig {
	
	/*@Autowired
	private DataSource dataSource;*/
	
	@Autowired
	private SecurityProperties securityProperties;
	
	@Autowired
	private UserDetailsService userDetailsService;
	
	/**
	 * token持久化初始类，自动建表
	 * https://vertonur.iteye.com/blog/1995867
	 */
	/*@Bean
	@ConditionalOnMissingBean(PersistentTokenRepository.class)
	public PersistentTokenRepository persistentTokenRepository() {
		BrowserRememberMeJdbcTokenRepositoryImpl tokenRepository = new BrowserRememberMeJdbcTokenRepositoryImpl();
		tokenRepository.setDataSource(dataSource);
		// 在启动的时候创建一张表
		// 启动一次自动生成表后注释掉
		// tokenRepository.setCreateTableOnStartup(true);
		return tokenRepository;
	}*/
	
	/**
	 * session失效时的处理策略配置
	 */
	@Bean
	@ConditionalOnMissingBean(InvalidSessionStrategy.class)
	public InvalidSessionStrategy invalidSessionStrategy(){
		return new BrowserInvalidSessionStrategy(securityProperties);
	}
	
	/**
	 * 并发登录导致前一个session失效时的处理策略配置
	 */
	@Bean
	@ConditionalOnMissingBean(SessionInformationExpiredStrategy.class)
	public SessionInformationExpiredStrategy sessionInformationExpiredStrategy(){
		return new BrowserExpiredSessionStrategy(securityProperties);
	}
	
	/**
	 * 退出登录处理器配置  方便给用户覆盖掉默认的退出登录成功处理器
	 */
	@Bean
	@ConditionalOnMissingBean(LogoutSuccessHandler.class)
	public LogoutSuccessHandler logoutSuccessHandler(){
		return new BrowserLogoutSuccessHandler(securityProperties.getBrowser().getSignOutSuccessUrl());
	}
	
	/**
	 * 登录成功处理
	 */
	@Bean
	@ConditionalOnMissingBean(AuthenticationSuccessHandler.class)
	public AuthenticationSuccessHandler authenticationSuccessHandler(){
		return new BrowserAuthenticationSuccessHandler();
	}
	
	/**
	 * 登录失败处理
	 */
	@Bean
	@ConditionalOnMissingBean(AuthenticationFailureHandler.class)
	public AuthenticationFailureHandler authenticationFailureHandler(){
		return new BrowserAuthenticationFailureHandler();
	}
	
	/**
	 * 解决remember-me不稳定的问题
	 * https://vertonur.iteye.com/blog/1995867
	 */
	@Bean
	@ConditionalOnBean(UserDetailsService.class)
	@ConditionalOnMissingBean(TokenBasedRememberMeServices.class)
	public RememberMeServices rememberMeServices(){
		TokenBasedRememberMeServices services = new TokenBasedRememberMeServices(CommonConstants.REMEMBER_ME_KEY, userDetailsService);
		services.setTokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds());
		return services;
	}
	
}
